package models;

import java.util.Date;

/**
 * Payment objects contain data about a payment made by a client.
 */
public class Payment extends DatabaseModel implements Searchable {
	
	private Client client;
	private double amount;
	private Date date;
	private String comment;

	/**
	 * Create a Payment with empty data
	 */
	public Payment() {
		this(null, 0, getTodaysDate(), "");
	}
		
	/**
	 * Create a payment filled with data.
	 * @param client that made the payment
	 * @param amount Paid paid amount
	 * @param date when the payment was processed
	 * @param comment comment (could be empty)
	 */
	public Payment(Client client, double amount, Date date, String comment) {
		this.client = client;
		this.amount = amount;
		this.date = date;
		this.comment = comment;
	}
	
	/**
	 * Same as {@link #Payment(Client, double, Date, String)}, but 
	 * with an id (generated by the database) as well.
	 */
	public Payment(int id, Client client, double amount, Date date, String comment) {
		this(client, amount, date, comment);
		setId(id);
	}	

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isSearchMatch(String searchString) {
		return (
			client.isSearchMatch(searchString) ||
			(""+amount).contains(searchString) ||
			getDateString().toLowerCase().contains(searchString.toLowerCase()) ||
			comment.toLowerCase().contains(searchString.toLowerCase())
		);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String[] getDataHeaders() {
		String[] headers = { "client", "amount", "date", "comment" };
		return headers;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String[] getData() {
		String[] data = { "" + this.client.getId() , "" + this.amount, getDateString(), this.comment};
		return data;
	}
		
	public Client getClient() {
		return client;
	}
	
	public void setClient(Client client) {
		this.client = client;
	}

	public double getAmount() {
		return amount;
	}

	public void setAmount(double amount) {
		this.amount = amount;
	}
	
	/**
	 * Get the date as a String (formatted accoring to {@link #dbDateFormat}, so suited for database). 
	 * @return date formatted as String
	 */
	public String getDateString(){
	    return dbDateFormat.format(date);
	}

	public void setDate(Date date) {
		this.date = date;
	}
	
	public Date getDate(){
		return date;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		long temp;
		temp = Double.doubleToLongBits(amount);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		result = prime * result + ((client == null) ? 0 : client.hashCode());
		result = prime * result + ((comment == null) ? 0 : comment.hashCode());
		result = prime * result + ((date == null) ? 0 : date.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		Payment other = (Payment) obj;
		if (Double.doubleToLongBits(amount) != Double
				.doubleToLongBits(other.amount))
			return false;
		if (client == null) {
			if (other.client != null)
				return false;
		} else if (!client.equals(other.client))
			return false;
		if (comment == null) {
			if (other.comment != null)
				return false;
		} else if (!comment.equals(other.comment))
			return false;
		if (date == null) {
			if (other.date != null)
				return false;
		} else if (!date.equals(other.date))
			return false;
		return true;
	}
	
}

